/**
 * 
 */
package qy.jalgotrade.optimizer.base;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import qy.jalgotrade.utils.PySpecs.Iter;

/**
 * Source for backtesting parameters. This class is thread safe.
 * 
 * @author c-geo
 *
 */
public class ParameterSource {

	private Iterator<Parameters> __iter;

	/**
	 * <pre>
	 * params (iterable): __iter__() 返回需为 Parameters 实例, 否则不能同时支持 *args 和 **kwargs:
	 * e.g.:
	 *     def params_gen():
	 *         p1 = [...]
	 *         p2 = [...]
	 *         kwp1 = [...]
	 *         kwp2 = [...]
	 *         for e in itertools.product(p1, p2, kwp1, kwp2):
	 *             yield Parameters(*(e[0], e[1]),
	 *                              **{"kwp1": e[2], "kwp2": e[3]})
	 * </pre>
	 * 
	 * @param params
	 */
	public ParameterSource(Iter<Parameters> params) {

		__iter = params.__iter__();
	}

	/**
	 * Returns the next parameters to use in a backtest. If there are no more parameters to try then an
	 * empty list is returned.
	 * 
	 * @param count The max number of parameters to return.
	 * @return list of Parameters.
	 */
	public List<Parameters> getNext(int count) {

		assert count > 0 : "Invalid number of parameters";
		List<Parameters> ret = new ArrayList<>();
		synchronized (this) {
			if (__iter != null) {
				try {
					while (count-- > 0) {
						Parameters params = __iter.next();
						ret.add(params);
					}
				} catch (NoSuchElementException e) {
					__iter = null;
				}
			}
		}
		return ret;
	}

	/**
	 * 
	 * @return
	 */
	public synchronized boolean eof() {

		return __iter == null;
	}
}
